/**
 *  Platypus: Page Layout and Typesetting Software (free at platypus.pz.org)
 *
 *  Platypus is (c) Copyright 2012 Pacific Data Works LLC. All Rights Reserved.
 *  Licensed under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html)
 */
package org.pz.platypus.parser;

import org.pz.platypus.GDD;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * @author alb
 *
 * Extracts the root of a command. The root is the part that at the beginning of the
 * command that remains the same regardless of parameters. To wit:
 * - commands with no parameters, it's the whole command: [+i]
 * - commands with 1 parameter, it's everything up to the ':' fsize: in [fsize:12pt]
 * -                            or everything up to the first space (in which case the : is added)
 * - commands with 2+ parameters, it's the family name, so [font| in [font|size:12pt|face:...
 *
 */
public class CommandRootExtractor
{
    private GDD gdd;

    public CommandRootExtractor( GDD Gdd )
    {
        gdd = checkNotNull( Gdd );
    }

    public String getRoot( final ParseContext Context )
           throws NullPointerException, IndexOutOfBoundsException
    {
        ParseContext context = checkNotNull( Context );

        int i;
        char c;
        StringBuilder root = new StringBuilder( 15 );

        // these commands do not contain a : or a | after the root,
        // so they must be tested for explicitly
        if( context.chars[context.startPoint] == '[' &&
                context.chars[context.startPoint+1] == '*' ) {
            return( "[*" );
        }

        if( context.chars[context.startPoint] == '[' &&
                context.chars[context.startPoint+1] == '$' ) {
            return( "[$" );
        }

        for( i = context.startPoint; ; i++ )
        {
            if ( context.isEnd( i )) {
                String unclosedCommand = context.getContent().substring( context.startPoint, i );
                gdd.log.warning(
                    gdd.getLit( "FILE#" ) + context.source.getFileNumber() + " " +
                    gdd.getLit( "LINE#" ) + context.source.getLineNumber() + " "  +
                    gdd.getLit( "ERROR.MALFORMED_COMMAND" ) +": " + unclosedCommand );
                throw new IndexOutOfBoundsException( null );
            }

            c = context.chars[i];
            root.append( c );
            //curr: need to detect whitespace (as an error)
            if( c == ']' || c == '|' || c == ':' || c == ' ' ) {
                return( c == ' ' ? root.toString().trim() + ":" : root.toString() );
            }
        }
    }
}
